package raytracer.geometry;

import java.text.DecimalFormat;

public class Transformation {

	protected float[][] matrix = new float[4][4];

	protected Transformation() {
		for (int i = 0; i < 4; i++) {
			for (int j = 0; j < 4; j++) {
				this.matrix[i][j] = 0;
			}
		}
	}

	// modified by Sascha 28.06.12: Vector in length == 3
	public float[] apply(float[] vectorIn) {
		
		float[] vector;
		
		if (vectorIn.length == 3)
		{
			vector = new float[4];
			vector[0] = vectorIn[0];
			vector[1] = vectorIn[1];
			vector[2] = vectorIn[2];
			vector[3] = 1.0f;
		}
		else
		{
			vector = vectorIn;
		}
		
		float[] result = new float[4];
		for (int row = 0; row < 4; ++row) {
			for (int col = 0; col < 4; ++col) {
				result[row] += matrix[row][col] * vector[col];
			}
		}
		return result;
	}

	public Transformation combine(Transformation other) {
		Transformation result = new Transformation();
		for (int res = 0; res < 4; res++) {
			for (int row = 0; row < 4; ++row) {
				for (int col = 0; col < 4; ++col) {
					result.matrix[row][res] += this.matrix[row][col] * other.matrix[col][res];
				}
			}
		}
		return result;
	}

	public Transformation inverse() {
		// TODO general inverse ...
		return null;
	}

	@Override
	public String toString() {
		DecimalFormat df = new DecimalFormat(",###0.0000");
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < 4; ++i) {
			sb.append("[ ");
			for (int j = 0; j < 4; ++j) {
				sb.append("[");
				sb.append(df.format(matrix[i][j]));
				sb.append("] ");
			}
			sb.append("]\n");
		}
		return sb.toString();
	}

}
